package com.xhai.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.codec.Base64;
import com.xhai.common.constant.ConfigConstants;
import com.xhai.common.constant.RedisConstants;
import com.xhai.common.domain.ResponseResult;
import com.xhai.common.domain.login.CaptchaEntity;
import com.xhai.common.cache.RedisCache;
import com.xhai.common.utils.IdUtils;
import com.xhai.service.SysConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author xhai
 * @description 验证码控制器
 * @date 2025/5/25
 */
@RestController
@RequestMapping("/captcha")
@Tag(name = "验证码控制器", description = "验证码控制器")
public class CaptchaController {

    @Resource
    private SysConfigService sysConfigService;
    @Resource
    private RedisCache redisCache;

    /**
     * 获取验证码图片
     *
     * @return 验证码图片二进制数据
     */
    @GetMapping("/getCaptchaImage")
    @Operation(summary = "获取验证码图片", description = "获取验证码图片")
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "登录成功"),
            @ApiResponse(responseCode = "400", description = "登录失败")
    })
    public ResponseResult<?> getCaptchaImage() {
        CaptchaEntity captchaEntity = new CaptchaEntity();
        // 获取验证码校验是否开启
        boolean captchaEnabled = sysConfigService.selectCaptchaCheckEnabled();
        if (!captchaEnabled) {
            captchaEntity.setEnabled(captchaEnabled);
            return ResponseResult.success(captchaEntity);
        }

        // 生成验证码，将验证码存入Redis
        String uuid = IdUtils.simpleUUID();
        // 获取验证码校验方式
        String captchaCheckMode = sysConfigService.selectCaptchaCheckMode();

        // 根据不同校验方式生成校验码
        String captchaCode = "";
        BufferedImage image = null;
        switch (captchaCheckMode) {
            // 图片
            case ConfigConstants.SYS_CAPTCHA_CHECK_MODE_PICTURE: {
                LineCaptcha captcha = CaptchaUtil.createLineCaptcha(120, 40, 4, 15);
                captchaCode = captcha.getCode();
                image = captcha.getImage();
            }
            break;
            // 其他
            case ConfigConstants.SYS_CAPTCHA_CHECK_MODE_OTHER: {
                System.out.println(ConfigConstants.SYS_CAPTCHA_CHECK_MODE_OTHER);
            }
            break;
            default:
                break;
        }

        // 保存验证码uuid和code到redis
        String captchaKey = RedisConstants.REDIS_KEY_PREFIX_CAPTCHA + uuid;
        redisCache.setCacheObject(captchaKey, captchaCode, RedisConstants.REDIS_KEY_EXPIRE_CAPTCHA, TimeUnit.MINUTES);

        switch (captchaCheckMode) {
            // 图片
            case ConfigConstants.SYS_CAPTCHA_CHECK_MODE_PICTURE: {
                // 将验证码唯一标识、校验方式、图片返回前端
                // 图片转换
                FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
                try {
                    boolean suc = ImageIO.write(image, "PNG", outputStream);
                    if (!suc) {
                        return ResponseResult.fail("生成校验码图片失败");
                    }
                } catch (IOException e) {
                    return ResponseResult.fail(e.getMessage());
                }

                captchaEntity.setUuid(uuid);
                captchaEntity.setMode(captchaCheckMode);
                captchaEntity.setImage(Base64.encode(outputStream.toByteArray()));
                captchaEntity.setEnabled(captchaEnabled);
            }
            break;
            // 其他
            case ConfigConstants.SYS_CAPTCHA_CHECK_MODE_OTHER: {
                System.out.println(ConfigConstants.SYS_CAPTCHA_CHECK_MODE_OTHER);
            }
            break;
            default:
                break;
        }

        return ResponseResult.success(captchaEntity);
    }
}
